import * as cc from "cc";
import SDK from "./SDK";
import { EventType } from "../../GameSpecial/GameEventType";
import EventManager from "../../Common/EventManager";
import http_request from "../../Common/http_request";
import { UserInfo } from "../../GameSpecial/PlayerDataTemplate";
import ALDManager from "../../Common/ALDManager";
import { AdConfig } from "../../GameSpecial/AdConfig";
import { GlobalEnum } from "../../GameSpecial/GlobalEnum";
import GlobalData from "../../Common/GlobalData";

const wx = window["wx"];
export default class WXSDK extends SDK {
    protected apiName: string = 'wx';
    public sceneid = 0;
    protected channel_id;

    public init() {
        this.api = window[this.apiName];

        this.systemInfo = this.api.getSystemInfoSync();
        systemInfo = this.systemInfo;
        screenSize.width = systemInfo.screenWidth;
        screenSize.height = systemInfo.screenHeight;

        console.log("系统信息：");
        console.log(JSON.stringify(this.systemInfo));

        // this.api.onShareAppMessage(() => ({}));
        this.api.showShareMenu({ withShareTicket: false });

        this.login();

        let ids = this.getAllBannerIds();
        BannerPool.init(ids);

        this.updateGame();
    }
    /**游戏包体更新 */
    protected updateGame() {
        const updateManager = wx.getUpdateManager()
        updateManager.onCheckForUpdate(function (res) {
            // 请求完新版本信息的回调
            console.log(res.hasUpdate)
        });
        updateManager.onUpdateReady(function () {
            wx.showModal({
                title: '更新提示',
                content: '新版本已经准备好，是否重启应用？',
                success: function (res) {
                    if (res.confirm) {
                        // 新的版本已经下载好，调用 applyUpdate 应用新版本并重启
                        updateManager.applyUpdate()

                    }
                },
                showCancel: false,
                cancelText: '',
                cancelColor: '',
                confirmText: '确定',
                confirmColor: '#576B95',
                fail: (res: any) => { },
                complete: (res: any) => { }
            })
        });
        updateManager.onUpdateFailed(function () {
            // 新版本下载失败
        });
    }

    /**
     * 使用微信小游戏内置方法
     * @param {object} wCall    回调函数 
     * @param {object} self     识别对象
     */
    public login(wCall = null, self = null,) {
        // window['game_id'] = this.game_id;
        let launch_data = this.api.getLaunchOptionsSync(); //获取微信登陆信息 
        console.log('launch_data', launch_data);
        this.channel_id = launch_data.query.channelId;
        this.sceneid = launch_data.scene;
        let that = this;
        this.api.login({
            success: (res) => {
                console.log('wx loagin success!!!', res);
                if (res.code) {
                    let codeUrl = "v1.1/api/User/sendSessionCode.html";
                    http_request.postRequest(http_request.url_login + codeUrl, { "code": res.code }, (login_res) => {
                        console.log('request sendSessionCode', login_res);
                        UserInfo.needuserinfo = login_res.result.needuserinfo;
                        UserInfo.openid = login_res.result.openid;
                        UserInfo.sessid = login_res.result.sessid;
                        UserInfo.userid = login_res.result.userid;
                        let ald = new ALDManager();
                        ald.init(UserInfo.openid);
                        onShowShareMenu(login_res.result.sessid, that);
                        EventManager.emit(EventType.Common.SDKEvent.inited);
                        //从其他游戏跳转到本游戏时，上报数据
                        let uclickUl = http_request.url_buy + "v1.1/api/Activity/uclick.html";
                        let fromapp = launch_data.referrerInfo.appId ? launch_data.referrerInfo.appId : "";
                        let key = launch_data.query.key ? launch_data.query.key : "";
                        let msg = {
                            appid: this.config.appId,
                            openid: cc.sys.localStorage.getItem("openid"),
                            // posttime: Timer_manager.getInstance().getNowTimes(),
                            posttime: Math.floor(Date.now() * 0.001),
                            key: key,
                            wxopenid: login_res.result.openid,
                            fromapp: fromapp,
                        }
                        http_request.postRequest(uclickUl, msg, (uclickData) => {
                            console.log('uclickData', uclickData);
                            onShow(false, uclickData.Result.OpenId);
                            cc.sys.localStorage.setItem("openid", uclickData.Result.OpenId);
                        });
                        //用户授权
                        // getSetting();
                    });
                }
            },
            fail: (res) => {
                console.log('login失败', res);
            }
        })

        function getSetting() {
            const version = wx.getSystemInfoSync().SDKVersion
            const verres = compareVersion(version, '2.0.1');
            console.log('verres', verres);

            window['user_info'] = [];

            wx.getSetting({
                success(res) {
                    console.log('获取微信用户当前设置成功', res);
                    if (res.authSetting['scope.userInfo'] || verres != 1) {
                        console.log('用户无授权');
                        wx.getUserInfo({
                            success(res) {
                                console.log('wx.getUserInfo', res);
                                if (typeof res.userInfo == "undefined" || res.errMsg == "getUserInfo:fail auth deny") {
                                    console.log(res.errMsg)
                                }
                                else {
                                    window['user_info'] = res.userInfo;
                                    // onShow(false);
                                }
                            }
                        })
                    } else {
                        console.log('创建授权按钮');
                        let button = wx.createUserInfoButton({
                            type: 'text',
                            text: '',
                            style: {
                                left: 0,
                                top: 0,
                                width: 1334,
                                height: 1334,
                                lineHeight: 1334,
                                textAlign: 'center',
                                backgroundColor: '',
                                color: '',
                                fontSize: 18,
                                opacity: 0.1,
                                borderRadius: 4
                            }
                        })
                        // console.log("wx button show");
                        button.onTap((res) => {
                            if (typeof res.userInfo == "undefined" || res.errMsg == "getUserInfo:fail auth deny") {
                                console.log(res.errMsg)
                            }
                            else {
                                console.log('wx 授权成功', res);
                                // http_request.Instance.postRequest("report/auth", that.post_data, (auth_res: any) => {

                                // });
                                button.destroy();
                                window['user_info'] = res.userInfo;
                                // onShow(true);
                            }
                        })
                    }
                }
            })
        }

        function onShow(useCb = false, game_openid) {

            that.onshow_time = wx.getPerformance().now();
            // 微信小程序从后台回到小程序时候调用
            wx.onShow(function () {
                that.onshow_time = wx.getPerformance().now();
                EventManager.emit(EventType.Common.AudioEvent.resume);
                EventManager.emit(EventType.Common.SDKEvent.show);
            });

            // 微信小程序隐藏到后台
            wx.onHide(function (e) {
                //判断是否点击banner跳出游戏
                try {
                    EventManager.emit(EventType.Common.AudioEvent.resume);
                    if (EventManager.emit(EventType.Common.SDKEvent.hide, e), !e || !e.mode) return;
                    if ("close" === e.mode) return EventManager.emit(EventType.Common.SDKEvent.hide, e);
                    if (!e.targetPagePath) return;
                    if (-1 !== e.targetPagePath.indexOf("weixinadinfo") && -1 !== e.targetPagePath.indexOf("gdt_vid")) return -1 !== e.targetPagePath.indexOf("mp.weixin.qq.com/mp/ad_biz_info") ? e.adType = "关注公众号链接" : e.adType = "电商链接",
                        EventManager.emit(EventType.Common.SDKEvent.touchBanner, e);
                    if (-1 !== e.targetPagePath.indexOf("SnsAdNativeLandingPagesPreviewUI")) return e.adType = "APP下载页",
                        EventManager.emit(EventType.Common.SDKEvent.touchBanner, e);
                    "hide" === e.mode ? -1 !== e.targetPagePath.indexOf("SnsAdNativeLandingPagesPreviewUI") ? (e.adType = "APP下载页",
                        EventManager.emit(EventType.Common.SDKEvent.touchBanner, e)) : -1 !== e.targetPagePath.indexOf("weixinadinfo") && -1 !== e.targetPagePath.indexOf("gdt_vid") ? (-1 !== e.targetPagePath.indexOf("mp.weixin.qq.com/mp/ad_biz_info") ? e.adType = "关注公众号链接" : e.adType = "电商链接",
                            EventManager.emit(EventType.Common.SDKEvent.touchBanner, e)) : -1 !== e.targetPagePath.indexOf("SelectConversationUI") || -1 !== e.targetPagePath.indexOf("MMUINavigationController") ? "" : -1 !== e.targetPagePath.indexOf("mp.weixin.qq.com/mp/wapreportwxadevlog?action=get_page&appid=wx") ? "" : -1 === e.targetPagePath.indexOf("AppBrandProfileUI") && -1 === e.targetPagePath.indexOf("NewWAProfileViewController") || "" : "launchMiniProgram" === e.mode ? -1 !== e.targetPagePath.indexOf("weixinadinfo") && -1 !== e.targetPagePath.indexOf("gdt_vid") ? (e.adType = "微信小游戏",
                                EventManager.emit(EventType.Common.SDKEvent.touchBanner, e)) : -1 !== e.targetPagePath.indexOf("wx") && 1 : "back" === e.mode && 9 === e.targetAction && -1 !== e.targetPagePath.indexOf("wx") && 1;
                } catch (e) {
                    console.error(e);
                }

                that.onhide_time = wx.getPerformance().now();
                let dif_time = Math.floor((that.onhide_time - that.onshow_time) / 1000);
                if (!game_openid) return;
                // 记录玩家在当前游戏中停留的时长
                let url = http_request.url_buy + "v1.1/api/Activity/stay.html";
                let online_post_data = {
                    appid: that.config.appId,
                    openid: game_openid,
                    posttime: Math.floor(Date.now() * 0.001),
                    time: dif_time
                };
                http_request.postRequest(url, online_post_data, (online_time_res: any) => { });
                EventManager.emit(EventType.Common.SDKEvent.hide);
            }.bind(this));
            wCall && wCall.call(self);
        }

        function compareVersion(v1, v2) {
            v1 = v1.split('.')
            v2 = v2.split('.')
            const len = Math.max(v1.length, v2.length)

            while (v1.length < len) {
                v1.push('0')
            }
            while (v2.length < len) {
                v2.push('0')
            }

            for (let i = 0; i < len; i++) {
                const num1 = parseInt(v1[i])
                const num2 = parseInt(v2[i])

                if (num1 > num2) {
                    return 1
                } else if (num1 < num2) {
                    return -1
                }
            }

            return 0;
        }
        //分享图片与标题设置
        function onShowShareMenu(sessid, target) {
            let url = "v1.1/api/Utils/init.html";
            http_request.postRequest(http_request.url_login + url, { "sessid": sessid }, (share_info_res: any) => {
                target.objShareData = share_info_res.result.share;
                wx.showShareMenu({
                    withShareTicket: true
                });
                let index = Math.floor(Math.random() * (target.objShareData.length - 1));
                console.log('onShareAppMessage index', index);
                console.log('share_info_res', share_info_res.result);
                //缓存关卡数据配置
                GlobalData.set(GlobalEnum.Common.GlobalDataType.levelDataVersion, JSON.stringify(share_info_res.result.config));

                wx.onShareAppMessage(() => {
                    return {
                        title: share_info_res.result.share[index].title,
                        imageUrl: share_info_res.result.share[index].img // 图片 URL
                    }
                })

            })
        }
    }

    public triggerGC() {
        this.api.triggerGC();
    }

    /***********************************************************************激励视频***********************************************************************/
    public showVideoAd(videoName?: any) {
        let id = this.getVideoAdUnitId(videoName);
        if (!id) {
            this.onVideoFail("视频id获取失败");
            return;
        }
        if (!this.videoAd) {
            this.videoAd = this.api.createRewardedVideoAd({ adUnitId: id });
            this.videoAd.onLoad(() => {
                console.log("视频广告加载完毕");
            });
            this.videoAd.onError((err) => {
                console.log("视频广告错误：", JSON.stringify(err));
            });
            this.videoAd.onClose((res) => {
                // 小于 2.1.0 的基础库版本，res 是一个 undefined
                if (res && res.isEnded || res === undefined) {
                    this.onVideoSuccess();
                } else {
                    this.onVideoQuit();
                    this.onVideoHide();
                }
            });
        }
        this.videoAd.show().then(this.onVideoShow.bind(this)).catch((err) => {
            this.videoAd.load().then(() => {
                this.videoAd.show().then(this.onVideoShow.bind(this));
            }).catch(this.onVideoFail.bind(this));
        });
    }


    /***********************************************************************banner广告***********************************************************************/
    /**
     * 显示banner
     * @param data 
     * @param data.bannerID AdConfig.bannerID中记录的id名称字符串，将优先根据该值获取广告id
     * @param data.id       banner广告id，data.bannerID不存在时，使用该值作为广告id，若data.id也不存在，则使用默认的广告id
     * @param data.style    banner尺寸位置等信息
     */
    public showBanner(data: { id: string, bannerID: string, style: any }) {
        if (!!data.bannerID && !data.id) {
            data.id = AdConfig.bannerID[data.bannerID];
            if (!data.id) {
                data.id = this.getAllBannerIds()[0];
            }
        } else if (!!data.id && !data.bannerID) {
            let v = data.id;
            let k = "";
            for (let key in AdConfig.bannerID) {
                if (AdConfig.bannerID[key] == v) {
                    k = key;
                    break;
                }
            }
            data.bannerID = k;
        } else if (!data.id && !data.bannerID) {
            console.error("未传入banner参数，不进行显示！");
            return;
            // data.bannerID = "lobby";
            // data.id = AdConfig.bannerID[data.bannerID];
        }
        BannerPool.show(data);
    }
    /**
     * 隐藏banner
     * @param data
     * @param data.bannerID     要隐藏的banner所属的场景
     * @param data.refresh      banner隐藏后是否需要加载新的数据并缓存
     */
    public removeBanner(data?: { bannerID?: string, refresh?: boolean }) {
        BannerPool.hide(data);
    }
    //检测是否有可显示的banner，并根据结果执行相应的回调
    public checkVisibleBanner(success?: Function | { cb: Function, target?: any, data?: any }, fail?: Function | { cb: Function, target?: any, data?: any }) {
        if (BannerPool.haveBanner && !!success) {
            if (typeof success === "function") {
                success();
            } else {
                if (success.target) {
                    success.cb.call(success.target, success.data);
                } else {
                    success.cb(success.data);
                }
            }
        } else if (!BannerPool.haveBanner && !!fail) {
            if (typeof fail === "function") {
                fail();
            } else {
                if (fail.target) {
                    fail.cb.call(fail.target, fail.data);
                } else {
                    fail.cb(fail.data);
                }
            }
        }
    }

    /***********************************************************************插屏广告***********************************************************************/
    public showInterstitialAd(banner: boolean = false) {
        this.useBannerInsteadInsert = false;//取消功能：插屏显示失败时显示banner
        this.showBannerInsteadInsert();
        let id = this.getInsertAdUnitId();
        if (!id) {
            // this.showBannerInsteadInsert();
            return;
        }
        const version = this.systemInfo.SDKVersion;
        if (this.compareVersion(version, '2.6.0') < 0) {
            console.log('基础库版本过低');
            // this.showBannerInsteadInsert();
            //   // 如果希望用户在最新版本的客户端上体验您的小程序，可以这样子提示
            //   this.api.showModal({
            //     title: '提示',
            //     content: '当前微信版本过低，无法使用插屏广告，请升级到最新微信版本后重试。'
            //   })
            return;
        }
        let ad = this.api.createInterstitialAd({ adUnitId: id });
        ad.show().then(this.onInsertShow.bind(this));
        ad.onClose(this.onInsertHide.bind(this));
        ad.onError((err) => {
            this.onInsertErr(err);
            // this.showBannerInsteadInsert();
        });
    }

    /***********************************************************************震动功能***********************************************************************/
    //震动
    public vibrateShort() {
        this.api.vibrateShort({});
    }
    public vibrateLong() {
        this.api.vibrateLong({});
    }

    /***********************************************************************分享功能***********************************************************************/
    /**无激励分享&&带参分享 */
    shareAppMessage(query: string = "") {
        let index: number = Math.floor((Math.random() * this.shareTitleArr.length));
        let indeximg: number = Math.floor((Math.random() * this.shareImgArr.length));
        this.api.shareAppMessage({
            title: `${this.shareTitleArr[index]}`,
            imageUrl: `${this.shareImgArr[indeximg]}`,
            query: `${query}`,
        });
    }
    /**激励分享&&带参分享 */
    shareToAnyOne(success: Function, fail?: Function, query: string = '') {
        this.shareAppMessage(query);
        success();
    }

    /***********************************************************************小游戏跳转***********************************************************************/
    /**
     * 跳转游戏
     * @param data      要跳转的游戏ID等数据
     * @param cb        跳转回调，参数：是否跳转
     * @param target    回调函数调用者
     */
    public navigateToMiniProgram(data: any, cb?: (navigated: boolean, recommondData: any) => void) {
        //请求跳转
        let self = this;
        let url = http_request.url_ad + "v1.1/api/userpreclick.html";
        http_request.postRequest(url, {
            softid: self.config.appId,
            uid: UserInfo.openid,
            advid: data.appid,
            locationid: data.locationid,
            id: data.id,
        }, (res) => {
            console.log("请求跳转上报结果：", res);
        });
        this.api.navigateToMiniProgram({
            appId: data.appid,
            path: data.url,
            success(res) {
                // 跳转成功，数据上报
                console.log("跳转成功，上报数据,", res);
                EventManager.emit(EventType.Common.SDKEvent.navigateSuccess, data);
                cb && cb(true, data);
                let url = http_request.url_ad + "v1.1/api/userclick.html";
                http_request.postRequest(url, {
                    softid: self.config.appId,
                    uid: UserInfo.openid,
                    advid: data.appid,
                    locationid: data.locationid,
                    id: data.id,
                }, (data) => {
                    console.log("跳转成功上报结果：", data);
                });
            },
            fail() {
                EventManager.emit(EventType.Common.SDKEvent.navigateFail, data);
                cb && cb(false, data);
            }
        });
    }
}

/**屏幕实际尺寸 */
var screenSize = {
    width: 667,
    height: 320,
};

/**手机系统信息 */
var systemInfo: any;

/**
 * banner缓存模式，
 * 通用：
 * 砸蛋页挑选一个已加载好的进行显示；
 * 进砸蛋页时立即加载对应的banner；
 * 
 * 缓存模式：
 * 0：砸蛋页提前加载，其他位置的banner，需要显示时再加载；
 * 根据传入的ID显示对应的banner实例；
 * 
 * 1：全部提前加载，轮流显示；
 * 
 * 2：轮流显示，需要显示时再加载；
 * 
 * 3：根据传入的ID显示对应的banner实例；显示时再加载；
 * 
 * 4：显示时再加载；砸蛋页选择已显示时间大于刷新间隔、点击次数最少的banner进行展示，其他页面根据传入的ID显示对应的banner实例；
 * 
 * 5：显示时再加载；显示时，优先将全部banner展示一遍；
 * 再次显示时，从显示时间小于BANNER_REFRESH_INTERVAL的banner中选择显示时间最大的一个进行显示，
 * 使得每个banner尽快地达到展示时间
 * 
 */
const BannerCacheMode: number = 5;

/**显示banner时，是否显示提示信息 */
const DEBUG_BANNER_SHOW: boolean = false;

/**banner必须累计展示时间达到指定值才会刷新 */
const BANNER_REFRESH_INTERVAL: number = 10;

/**banner对象池 */
class BannerPool {
    protected static allBanners: BannerRecord[] = [];
    /**各场景/UI对应的banner数据 */
    protected static bannerSceneMap: { [scene: string]: BannerRecord } = {};
    /**banner广告id对应的banner数据 */
    protected static bannerIdMap: { [id: string]: BannerRecord } = {};
    /**当前正在显示的banner数据 */
    protected static curBanner: BannerRecord;
    /**当前显示的banner所属的场景/UI */
    protected static curBannerID: string;
    protected static curBannerPtr: number;
    /**所有banner广告id */
    protected static ids: string[];
    /**缓存的banner数量 */
    public static cacheBannerCount: number = 1;
    /**是否正在跳转到其他小游戏 */
    protected static navigating: boolean = false;
    /**玩家累计已点击的banner次数 */
    protected static bannerClickCount: number = 0;

    //#region 自动刷新功能：
    // /**持续显示banner的时间 */
    // protected static showElapsed: number = 0;
    /**banner持续显示时自动刷新的时间间隔 */
    protected static refreshDuration: number = 8;
    /**用于循环显示的banner数组 */
    protected static loopBanners: BannerRecord[] = [];
    /**循环显示的banner指针 */
    protected static loopPtr: number = 0;
    protected static refreshTimer: number = -1;
    /**刷新一个循环显示的banner */
    protected static refreshLoopBanner() {
        if (++this.loopPtr >= this.loopBanners.length) {
            this.loopPtr = 0;
        }
        let style;
        if (!!this.curBanner) {
            style = this.curBanner.style;
            this.curBanner.hide(false);
        }
        this.curBanner = this.loopBanners[this.loopPtr];
        this.curBanner.show(style);
    }
    /**开启计时器：自动刷新，循环显示banner */
    protected static setRefreshTimer() {
        if (this.refreshTimer >= 0) {
            return;
        }
        if (!!this.curBanner && !this.isZaDanBanner(this.curBanner.id)) {
            this.clearRefreshTimer();
            return;
        }
        this.refreshTimer = setInterval(() => {
            if (!this.curBanner) {
                return;
            }
            let id = this.curBanner.id;
            if (this.isZaDanBanner(id)) {
                this.clearRefreshTimer();
            } else {
                this.refreshLoopBanner();
            }
        }, this.refreshDuration * 1000);
    }
    /**停止自动刷新banner */
    protected static clearRefreshTimer() {
        if (this.refreshTimer >= 0) {
            clearTimeout(this.refreshTimer);
            this.refreshTimer = -1;
        }
    }
    //#endregion

    /**banner广告id是否为砸蛋页面的id */
    protected static isZaDanBanner(id: string) {
        // return false;
        switch (id) {
            case AdConfig.bannerID.touchBannerLevelToLose:
            case AdConfig.bannerID.touchBannerLevelToWin:
            case AdConfig.bannerID.touchBannerLoseToLobby:
            case AdConfig.bannerID.touchBannerWinToLobby:
            case AdConfig.bannerID.touchBannerUI:
                {
                    return true;
                }
            default: {
                return false;
            }
        }
    }

    public static init(ids: string[]) {
        this.bannerSceneMap = {};
        this.bannerIdMap = {};
        this.allBanners = [];
        this.loopBanners = [];
        this.curBanner = null;
        this.curBannerPtr = -1;
        this.ids = [].concat(ids);
        this.preLoadBanner();
        this.onEvents();
    }
    protected static preLoadBanner() {
        let map = {};
        for (let key in AdConfig.bannerID) {
            let id = AdConfig.bannerID[key];
            if (!!id) {
                if (!map[id]) {
                    let banner = new BannerRecord(id);
                    map[id] = banner;
                    switch (BannerCacheMode) {
                        case 0: {
                            if (this.isZaDanBanner(id)) {
                                banner.load();
                            }
                            this.loopBanners.push(banner);
                            break;
                        }
                        case 1: {
                            banner.load();
                            this.loopBanners.push(banner);
                            break;
                        }
                        case 2: {
                            this.loopBanners.push(banner);
                            break;
                        }
                        case 3: {
                            this.loopBanners.push(banner);
                            break;
                        }
                        case 4: {
                            this.loopBanners.push(banner);
                            break;
                        }
                        case 5: {
                            this.loopBanners.push(banner);
                            break;
                        }
                    }
                }
                this.bannerSceneMap[key] = map[id];
            }
        }
        this.bannerIdMap = map;
    }

    protected static onEvents() {
        // EventManager.on(EventType.Common.SDKEvent.show, this.onGameShow, this);
        EventManager.on(EventType.Common.SDKEvent.touchBanner, this.onTouchBanner, this);
        EventManager.on(EventType.Common.SDKEvent.navigateSuccess, this.onNavigateSuccess, this);
        EventManager.on(EventType.Common.UIEvent.entered, this.onEnterScene, this);

        if (DEBUG_BANNER_SHOW) {
            EventManager.on(EventType.Common.SDKEvent.showBanner, this.showTipBannerShowStart, this);
            EventManager.on(EventType.Common.SDKEvent.showBannerSuccess, this.showTipBannerShowSuccess, this);
        }

    }
    /**文本提示显示banner */
    protected static showTipBannerShowSuccess() {
        EventManager.emit(EventType.Common.UIEvent.showTip, "banner显示成功");
    }
    protected static showTipBannerShowStart() {
        EventManager.emit(EventType.Common.UIEvent.showTip, "开始显示banner");
    }
    /**进入场景时预加载对应的banner */
    protected static onEnterScene(ui) {
        switch (ui) {
            case GlobalEnum.UI.touchBanner1:
            case GlobalEnum.UI.touchBanner2:
            case GlobalEnum.UI.touchBanner3: {
                let banner = this.bannerIdMap[AdConfig.bannerID.touchBannerUI];
                if (!banner) {

                } else if (banner.state == BannerState.inited) {
                    banner.load();
                }
                break;
            }
            //游戏关卡页中，显示新拉取的banner
            case GlobalEnum.UI.levelInfo: {
                this.hide();
                break;
            }
        }
    }
    protected static hideLevelInfoUIBanner() {
        setTimeout(() => {
            this.hide({
                bannerID: "banner1",
                refresh: false,
            });
        }, 5000);
    }
    protected static onNavigateSuccess(data) {
        this.navigating = true;
    }
    //切回游戏，统计banner点击事件
    protected static onGameShow() {
        if (!!this.navigating) {
            this.navigating = false;
        } else if (!!this.curBanner) {
            //上报数据
            this.reportClickBanner();
            //非砸蛋页面点击banner返回后刷新当前banner
            if (!this.isZaDanBanner(this.curBanner.id)) {
                this.curBanner.refresh(true);
            }
        }
    }
    //点击banner跳出游戏回调
    protected static onTouchBanner() {
        this.reportClickBanner();
        if (!!this.curBanner) {
            this.curBanner.addClickCount();
            this.curBanner.refresh(true);
        }
    }
    /**上报数据，记录banner点击事件 */
    protected static reportClickBanner() {
        let scene = this.curBannerID;
        BannerPool.bannerClickCount++;
        EventManager.emit(EventType.Common.ALDEvent.sendEvent, {
            eventName: "banner点击",
            data: {
                scene: scene,       //点击的banner所属的场景/UI
                count: BannerPool.bannerClickCount, //玩家已点击的次数
            },
        });
    }

    public static show(data: { id: string, bannerID: string, style?: any }) {
        switch (BannerCacheMode) {
            case 0: {
                this.showBannerMode0(data);
                break;
            }
            case 1: {
                this.showBannerMode1(data);
                break;
            }
            case 2: {
                this.showBannerMode2(data);
                break;
            }
            case 3: {
                this.showBannerMode3(data);
                break;
            }
            case 4: {
                this.showBannerMode4(data);
                break;
            }
            case 5: {
                this.showBannerMode5(data);
                break;
            }
        }
        this.showSuccess();
    }
    /**模式0：根据传入的ID显示对应的banner实例 */
    protected static showBannerMode0(data: { id: string, bannerID: string, style?: any }) {
        let style = data.style;
        if (!this.bannerSceneMap[data.bannerID]) {
            this.showFail(data.style);
            return;
        }
        if (!!this.curBanner) {
            if (this.curBannerID === data.bannerID) {
                this.curBanner.show(style);
            } else {
                //场景不同时显示新的banner或刷新当前banner
                this.curBannerID = data.bannerID;
                let banner = this.bannerSceneMap[this.curBannerID];
                if (banner !== this.curBanner) {
                    this.curBanner.hide(true);
                    this.curBanner = banner;
                    this.curBanner.show(style);
                } else {
                    this.curBanner.show(style);
                }
            }
        } else {
            this.curBannerID = data.bannerID;
            let banner = this.bannerSceneMap[this.curBannerID];
            this.curBanner = banner;
            this.curBanner.show(style);
        }
    }
    /**模式1：全部预加载好，轮流显示 */
    protected static showBannerMode1(data: { id: string, bannerID: string, style?: any }) {
        let style = data.style;
        if (!!this.curBanner) {
            this.curBanner.hide();
        }
        let c = this.loopBanners.length;
        for (let i = 0; i < c; ++i) {
            if (++this.loopPtr >= c) {
                this.loopPtr = 0;
            }
            let banner = this.loopBanners[this.loopPtr];
            if (banner.visible) {
                this.curBanner = this.loopBanners[this.loopPtr];
                this.curBanner.show(style);
                break;
            } else if (banner.state === BannerState.inited) {
                banner.load();
            }
        }
    }
    /**模式2：轮流显示，需要时再加载 */
    protected static showBannerMode2(data: { id: string, bannerID: string, style?: any }) {
        let style = data.style;
        if (!!this.curBanner) {
            this.curBanner.hide();
        }
        //砸蛋页挑选一个已加载好的banner显示
        if (this.isZaDanBanner(data.id)) {
            let b = false;
            let c = this.loopBanners.length;
            for (let i = 0; i < c; ++i) {
                if (++this.loopPtr >= c) {
                    this.loopPtr = 0;
                }
                let banner = this.loopBanners[this.loopPtr];
                if (banner.visible) {
                    this.curBanner = this.loopBanners[this.loopPtr];
                    this.curBanner.show(style);
                    b = true;
                    break;
                }
            }
            if (!b) {
                if (++this.loopPtr >= c) {
                    this.loopPtr = 0;
                }
                this.curBanner = this.loopBanners[this.loopPtr];
                this.curBanner.show(style);
            }
        } else {
            if (++this.loopPtr >= this.loopBanners.length) {
                this.loopPtr = 0;
            }
            this.curBanner = this.loopBanners[this.loopPtr];
            this.curBanner.show(style);
        }
    }
    /**模式3：根据传入的场景显示对应的banner */
    protected static showBannerMode3(data: { id: string, bannerID: string, style?: any }) {
        let style = data.style;
        if (!this.bannerSceneMap[data.bannerID]) {
            this.showFail(data.style);
            return;
        }
        if (!!this.curBanner) {
            if (this.curBannerID === data.bannerID) {
                this.curBanner.show(style);
            } else {
                //场景不同时显示新的banner或刷新当前banner
                this.curBannerID = data.bannerID;
                let banner = this.bannerSceneMap[this.curBannerID];
                if (banner !== this.curBanner) {
                    this.curBanner.hide(true);
                    this.curBanner = banner;
                    this.curBanner.show(style);
                } else {
                    this.curBanner.show(style);
                }
            }
        } else {
            this.curBannerID = data.bannerID;
            let banner = this.bannerSceneMap[this.curBannerID];
            this.curBanner = banner;
            this.curBanner.show(style);
        }
    }
    /**模式4：砸蛋页选择已显示时间大于刷新间隔、点击次数最少的banner进行展示，其他页面根据传入的场景显示对应的banner */
    protected static showBannerMode4(data: { id: string, bannerID: string, style?: any }) {
        if (data.bannerID.indexOf("touchBanner") < 0) {
            this.showBannerMode3(data);
            return;
        }
        let style = data.style;
        //砸蛋页选择显示时间大于刷新间隔、点击次数最少的banner
        let b = null;
        let bs = [];
        for (let key in this.bannerIdMap) {
            if (this.bannerIdMap[key].getShowTime() >= BANNER_REFRESH_INTERVAL) {
                bs.push(this.bannerIdMap[key]);
                // b = this.bannerIdMap[key];
                // t = this.bannerIdMap[key].showTime;
                console.log("banner.showTime:", this.bannerIdMap[key].getShowTime());
            }
        }
        if (bs.length > 0) {
            bs.sort((a, b) => {
                return a.clickCount - b.clickCount;
            });
            b = bs[0];
        }

        if (!!b) {
            console.log("筛选出的banner.showTime、clickCount:", b.getShowTime(), b.clickCount);
            if (!!this.curBanner) {
                if (this.curBanner === b) {
                    this.curBanner.show(style);
                } else {
                    //场景不同时显示新的banner或刷新当前banner
                    this.curBannerID = b.bannerID;
                    this.curBanner.hide(true);
                    this.curBanner = b;
                    this.curBanner.show(style);
                }
            } else {
                this.curBannerID = b.bannerID;
                this.curBanner = b;
                this.curBanner.show(style);
            }
        } else {
            this.showBannerMode3(data);
        }
    }
    /**模式5：先全部显示一遍，然后选择显示时间小于  BANNER_REFRESH_INTERVAL 的banner中显示时间最大的一个 */
    protected static showBannerMode5(data: { id: string, bannerID: string, style?: any }) {
        let style = data.style;
        let c = null;
        let bs = [];
        for (let key in this.bannerIdMap) {
            if (this.bannerIdMap[key].getShowTime() == 0) {
                c = this.bannerIdMap[key];
                break;
            }
            if (this.bannerIdMap[key].getShowTime() < BANNER_REFRESH_INTERVAL) {
                bs.push(this.bannerIdMap[key]);
            }
        }
        if (!!c) {
            if (!!this.curBanner) {
                this.curBanner.hide();
            }
            this.curBannerID = c.bannerID;
            this.curBanner = c;
            this.curBanner.show(style);
            return;
        }
        if (bs.length > 0) {
            bs.sort((a, b) => {
                return a.getShowTime() - b.getShowTime();
            });
            let banner = bs[bs.length - 1];
            if (!!this.curBanner && this.curBanner == banner) {
                this.curBanner.show(style);
            } else {
                if (!!this.curBanner) {
                    this.curBanner.hide();
                }
                this.curBannerID = banner.bannerID;
                this.curBanner = banner;
                this.curBanner.show(style);
            }
        } else {
            this.showBannerMode3(data);
        }

    }
    protected static showSuccess() {
        EventManager.emit(EventType.Common.SDKEvent.showBannerFinish);
    }
    protected static showFail(style) {
        EventManager.emit(EventType.Common.SDKEvent.showBannerFail, style);
    }

    public static hide(data?: { bannerID?: string, refresh?: boolean }) {
        if (!data) {
            if (!!this.curBanner) {
                this.curBanner.hide();
            }
        } else if (!!data.bannerID) {
            if (!!this.bannerSceneMap[data.bannerID]) {
                this.bannerSceneMap[data.bannerID].hide(data.refresh);
            }
            if (!!this.curBanner && this.curBanner.bannerID != data.bannerID) {
                this.curBanner.hide();
            }
        } else {
            if (!!this.curBanner) {
                this.curBanner.hide(data.refresh);
            }
        }
        this.curBanner = null;
    }

    /**是否有可显示的banner */
    public static get haveBanner() {
        for (const key in this.bannerIdMap) {
            if (this.bannerIdMap[key].visible) {
                return true;
            }
        }
        return false;
    }

    /**获取当前正在显示的banner数据，没有显示banner时将返回null */
    public static getCurBanner() {
        return this.curBanner;
    }
}

/**banner状态记录 */
class BannerRecord {
    /**banner广告id */
    public id: string;
    /**广告id对应在AdConfig.bannerID中的字段 */
    public bannerID: string;
    /**banner实例 */
    public banner: any;
    /**banner状态 */
    public state: BannerState;
    /**创建时间 */
    public createTime: number;
    /**展示次数 */
    public showCount: number;
    /**同一个banner实例可重复展示的最大次数 */
    public maxShowCount: number = 1;
    /**拉取成功的banner展示的总次数 */
    public totalShowCount: number;
    /**连续加载错误次数 */
    public errorCount: number;
    /**banner需要的坐标尺寸等 */
    public style: any;
    /**banenr实际尺寸 */
    public size: {
        width: number,
        height: number,
    };
    /**banner加载完成后是否需要立即显示 */
    public needShow: boolean = false;
    /**有效加载次数 */
    public loadCount: number = 0;
    /**banner实例点击次数 */
    public clickCount: number = 0;
    /**ID对应的banner点击总次数 */
    public totalClickCount: number = 0;
    public addClickCount() {
        this.clickCount++;
        this.totalClickCount++;
    }

    /**展示时间戳 */
    public showStartTime: number;
    /**一个banner实例累计展示的时间 */
    protected showTime: number;
    public getShowTime() {
        let time = this.showTime;
        if (this.state == BannerState.showing) {
            let t = Date.now();
            if (t.toString().length == 13) {
                t = Math.floor(t * 0.001);
            }
            time += t - this.showStartTime;
        }
        return time;
    }
    /**banner实例的累计展示时间是否已达到可以刷新的时间 */
    protected canRefresh(): boolean {
        if (this.showCount < 1) return false;
        let time = this.getShowTime();
        return time >= BANNER_REFRESH_INTERVAL;
    }
    protected updateShowStartTime() {
        let t = Date.now();
        if (t.toString().length == 13) {
            t = Math.floor(t * 0.001);
        }
        this.showStartTime = t;
    }
    protected updateShowTotalTime() {
        let t = Date.now();
        if (t.toString().length == 13) {
            t = Math.floor(t * 0.001);
        }
        this.showTime += (t - this.showStartTime);
    }

    public constructor(id: string, bannerID?: string) {
        this.id = id;
        if (!!bannerID) {
            this.bannerID = bannerID;
        } else {
            let v = id;
            let k = "";
            for (let key in AdConfig.bannerID) {
                if (AdConfig.bannerID[key] == v) {
                    k = key;
                    break;
                }
            }
            this.bannerID = k;
        }
        this.banner = null;
        this.state = BannerState.inited;
        this.createTime = 0;
        this.showCount = 0;
        this.errorCount = 0;
        this.style = {};
        this.size = { width: 300, height: 120 };//todo
        this.loadCount = 0;
        this.showStartTime = 0;
        this.showTime = 0;
        this.clickCount = 0;
        this.totalClickCount = 0;
    }
    public load() {
        if (this.state === BannerState.loading) {
            return;
        }
        this.destroy();

        let t = Date.now();
        if (t.toString().length == 13) {
            t = Math.floor(t * 0.001);
        }
        this.createTime = t;

        this.state = BannerState.loading;
        this.banner = wx.createBannerAd({
            adUnitId: this.id,
            style: {
                left: 0,
                top: screenSize.height - 120,
                width: 300,
            },
        });

        this.banner.onLoad(this.onLoad.bind(this));
        this.banner.onError(this.onError.bind(this));
        this.banner.onResize(this.onResize.bind(this));
    }
    public show(style?): boolean {
        if (!!style) {
            this.style = style;
        }
        switch (this.state) {
            case BannerState.error: {
                EventManager.emit(EventType.Common.SDKEvent.showBannerSuccess);
                break;
            }
            case BannerState.inited:
            case BannerState.destroyed:
                {
                    this.needShow = true;
                    this.load();
                    break;
                }
            case BannerState.loading: {
                this.needShow = true;
                break;
            }
            case BannerState.loadFinish: {
                if (null !== this.hideTimer) {
                    clearTimeout(this.hideTimer);
                    this.hideTimer = null;
                }
                this.setBannerStyle();
                this._showBanner();
                break;
            }
            case BannerState.hide: {
                this.setBannerStyle();
                this._showBanner();
                return true;
            }
            case BannerState.showing: {
                this.setBannerStyle();
                EventManager.emit(EventType.Common.SDKEvent.showBannerSuccess);
                return true;
            }
            default: {
                return false;
            }
        }
    }
    /**设置banner实例的位置 */
    protected setBannerStyle() {
        let banner = this.banner;
        let style = this.style;
        let size = this.size;
        if (undefined !== style.horizontal) {
            switch (style.horizontal) {
                case "left": {
                    banner.style.left = 0;
                    console.log("设置banner靠左左边距：", banner.style.left);
                    break;
                }
                case "right": {
                    banner.style.left = screenSize.width - size.width;
                    console.log("设置banner靠右左边距：", banner.style.left);
                    break;
                }
                case "middle": {
                    banner.style.left = (screenSize.width - size.width) * 0.5;
                    console.log("设置banner居中左边距：", banner.style.left);
                    break;
                }
                default: {
                    break;
                }
            }
        } else if (undefined !== style.left) {
            let rate = screenSize.width / GlobalData.get(GlobalEnum.Common.GlobalDataType.canvasTransform).width;
            banner.style.left = style.left * rate;
        } else if (undefined !== style.right) {
            let rate = screenSize.width / GlobalData.get(GlobalEnum.Common.GlobalDataType.canvasTransform).width;
            banner.style.left = screenSize.width - size.width - style.right * rate;
        }
        if (undefined !== style.top) {
            let rate = screenSize.height / GlobalData.get(GlobalEnum.Common.GlobalDataType.canvasTransform).height;
            banner.style.top = style.top * rate;
        } else if (undefined !== style.bottom) {
            let rate = screenSize.height / GlobalData.get(GlobalEnum.Common.GlobalDataType.canvasTransform).height;
            banner.style.top = screenSize.height - size.height - style.bottom * rate;
        } else {
            banner.style.top = screenSize.height - size.height;
        }
    }
    /**显示banner实例 */
    protected _showBanner() {
        if (!this.banner) {
            return;
        }
        this.banner.show().then(this.onShow.bind(this)).catch((err) => {
            this.onShowError();
        });
    }
    protected onShow() {
        this.updateShowStartTime();
        this.showCount += 1;
        this.totalShowCount += 1;
        this.state = BannerState.showing;
        EventManager.emit(EventType.Common.SDKEvent.showBannerSuccess);
    }
    protected onShowError() {
        this.updateShowStartTime();
        this.showCount += 1;
        this.totalShowCount += 1;
        this.state = BannerState.error;
        EventManager.emit(EventType.Common.SDKEvent.showBannerSuccess);
    }
    /**
     * 隐藏banner
     * @param refresh 是否刷新banner，默认不刷新
     */
    public hide(refresh: boolean = false) {
        this.needShow = false;
        switch (this.state) {
            case BannerState.showing: {
                this.updateShowTotalTime();
                this.banner.style.left = screenSize.width;
                // this.banner.hide();
                this.state = BannerState.hide;
                break;
            }
            default: {
                break;
            }
        }
    }
    public destroy() {
        if (this.state == BannerState.loading) return;
        if (!this.banner) return;

        let banner = this.banner;
        banner.offLoad();
        banner.offError();
        banner.offResize();
        banner.destroy();
        this.banner = null;

        this.state = BannerState.destroyed;
        this.showCount = 0;
        this.showTime = 0;
        this.clickCount = 0;
    }

    /**
     * 刷新banner实例
     * @param show      banner实例加载完成后是否需要立即显示
     * @param style     banner实例加载完成后的位置尺寸信息
     *  */
    public refresh(show: boolean, style?: any) {
        if (!!style) {
            this.style = style;
        }
        this.needShow = show;
        switch (this.state) {
            case BannerState.destroyed:
            case BannerState.inited: {
                this.load();
                break;
            }
            case BannerState.showing:
            case BannerState.hide: {
                if (this.canRefresh() && this.clickCount > 0) {
                    this.load();
                }
                break;
            }
        }
    }

    /**banner是否有效且可显示 */
    public get visible(): boolean {
        return this.state == BannerState.loadFinish
            || this.state == BannerState.showing
            || this.state == BannerState.hide;
    }

    //banner实例回调
    protected hideTimer: number = null;
    protected onLoad() {
        this.showCount = 0;
        this.errorCount = 0;
        this.showTime = 0;
        this.clickCount = 0;
        this.loadCount++;
        if (this.needShow) {
            this.needShow = false;
            this.setBannerStyle();
            this._showBanner();
        } else {
            this.state = BannerState.loadFinish;
            this.banner.style.left = screenSize.width;
            this.banner.show();
            // this.hideTimer = setTimeout(() => {
            //     this.banner.hide();
            //     this.hideTimer = null;
            // }, 500);
        }
    }
    protected onResize(size) {
        this.size = size;
        if (systemInfo.platform == "ios" && !!systemInfo.statusBarHeight && systemInfo.statusBarHeight > 20) {
            this.banner.style.top = systemInfo.screenHeight - this.size.height - 20;
        } else {
            this.banner.style.top = systemInfo.screenHeight - this.size.height;
        }
    }
    protected onError(err) {
        console.log("banner加载错误，ID：", this.id, "err:", err, "errCount:", this.errorCount);
        this.errorCount += 1;
        if (this.errorCount >= 2) {
            //连续加载错误2次则停止继续加载
            this.state = BannerState.error;
            if (this.needShow) {
                EventManager.emit(EventType.Common.SDKEvent.showBannerSuccess);
            }
        } else {
            //重新加载
            this.load();
        }
    }

}

/**banner状态类型 */
enum BannerState {
    inited,
    /**加载中 */
    loading,
    /**加载出错 */
    error,
    /**加载完毕 */
    loadFinish,
    /**正在显示 */
    showing,
    /**已隐藏 */
    hide,
    /**已销毁 */
    destroyed,
}
